#include <Hardware.h>
#include <NetTime.h>
#include <SD.h>

#ifdef REMAP_SD_SPI
SPIClass hspi(HSPI);
#endif

int8_t wakeUpSeconds = 60;               // 唤醒秒长，小于零不唤醒, 默认每分钟唤醒以更新时间
uint64_t wakeUpIOMask = WAKE_UP_IO_MASK; // 唤醒引脚掩码，为零无引脚唤醒,  默认两个按键均为唤醒脚

bool sdReady = false;

uint8_t getKey()
{
    gpio_num_t key_io[] = {KEY_UP_IO, KEY_DN_IO};

    uint64_t s = esp_sleep_get_ext1_wakeup_status();

    uint8_t key = KEY_EP;
    if (s & 0x400000000)
    {
        key = KEY_DN;
    }
    if (s & 0x8000000000)
    {
        key = KEY_UP;
    }

    for (int i = (key == KEY_DN) ? 1 : 0; i < 2; i++)
    {
        pinMode(key_io[i], INPUT_PULLUP);
        if (digitalRead(key_io[i]))
        {
            uint32_t ms = millis();
            do
            {
                delay(20);
            } while (digitalRead(key_io[i]));

            key = i * 2 + ((millis() - ms < 300) ? KEY_UP : KEY_BK);
        }
        gpio_reset_pin(key_io[i]);
    }

    dbLogValue("Key: ", key);
    return key;
}

void gpioResetPins()
{
    // 据说做了下面这些设置后电流从63uA下降到了3uA
    gpio_reset_pin(GPIO_NUM_0);
    gpio_reset_pin(GPIO_NUM_2);
    gpio_reset_pin(SD_CS);  // GPIO_NUM_4
    gpio_reset_pin(EPD_CS); // GPIO_NUM_5
    gpio_reset_pin(GPIO_NUM_12);
    gpio_reset_pin(GPIO_NUM_13);
    gpio_reset_pin(GPIO_NUM_14);
    gpio_reset_pin(GPIO_NUM_15);
    gpio_reset_pin(EPD_RST);  // GPIO_NUM_16
    gpio_reset_pin(EPD_BUSY); // GPIO_NUM_17
    gpio_reset_pin(EPD_DC);   // GPIO_NUM_19
    gpio_reset_pin(WAKE_IO);  // GPIO_NUM_25
    gpio_reset_pin(BEEP_IO);  // GPIO_NUM_26
    gpio_reset_pin(GPIO_NUM_27);
    gpio_reset_pin(GPIO_NUM_32);
    gpio_reset_pin(GPIO_NUM_33);
    // gpio_reset_pin(KEY_DN_IO); // GPIO_NUM_34
    gpio_reset_pin(GPIO_NUM_35);
    gpio_reset_pin(GPIO_NUM_36);
    gpio_reset_pin(GPIO_NUM_37);
    gpio_reset_pin(GPIO_NUM_38);
    // gpio_reset_pin(KEY_UP_IO); // GPIO_NUM_39
}

bool sdMount(bool side)
{
    if (side != sdReady)
    {
        if (side)
        {
            pinMode(WAKE_IO, OUTPUT);
            digitalWrite(WAKE_IO, HIGH);
#ifdef REMAP_SD_SPI
            hspi.begin(SCK, MISO, MOSI, SD_CS); // remap hspi for SD
            for (int i = 0; i < SD_RETRY_TIME && !sdReady; i++)
            {
                sdReady = SD.begin(SD_CS, hspi);
            }
#else
            for (int i = 0; i < SD_RETRY_TIME && !sdReady; i++)
            {
                sdReady = SD.begin(SD_CS);
            }
#endif
            if (sdReady)
            {
                dbLog("sd Ready!");
            }
            else
            {
                dbLog("sd not Ready!");
            }
        }
        else
        {
            SD.end();
            hspi.end();
            sdReady = false;
            digitalWrite(WAKE_IO, LOW);
            gpio_reset_pin(WAKE_IO);
        }
    }

    return sdReady;
}

#ifndef USE_BatterySense

// 超出电压应显示电量      0%,  20%,  40%,  60%,  80%, 100%
int const batVolt[] = {3300, 3510, 3710, 3820, 3940, 4200};
// 待机电量测量，每周记录一次电压
// 3.1 4726
// 3.8 4610
//  直接用电压查表法，反正只分5级，不需要准确

#define BatCY 2450   // 满电时引脚读数
#define BatHigh 4200 // 锂电池满电电压

int batteryLevel()
{
    pinMode(WAKE_IO, OUTPUT);
    pinMode(BATTERY_READ_IO, INPUT);

    digitalWrite(WAKE_IO, HIGH);
    delayMicroseconds(10);

    analogRead(BATTERY_READ_IO);
    // delay(10);
    // uint16_t voltage = analogRead(BATTERY_READ_IO) << 1; // 采样电压为一半
    
    uint16_t voltage = 0;
    for(int i = 0; i < 12; i++)
    {
        voltage += analogRead(BATTERY_READ_IO);
    }
    dbLogValue("\nVoltage = ", voltage/12);
    voltage /= 7; // voltage = (voltage/12 * (4200/2450) = voltage/12 * (12/7) = voltage/7

    digitalWrite(WAKE_IO, LOW);

#ifdef SHOW_VOLTAGE
    return voltage;
#else
    int lev = 0;
    while (batVolt[lev] < voltage && lev < 5)
        lev++;
    return lev;
#endif
}
#endif